Repository navigation
AMT coverage: g6-cli-plumbing-output-enco - #197
Conversation
Adversarial mutation-test coverage for the g6 slice: - crates/cli/tests/cli_dispatch.rs: end-to-end discrimination of all 8 dispatch arms through the compiled binary (schema ls/show, validate, schema-check, magic ls, build, solc artifact, subgraph, generate). - crates/cli/src/error/mod.rs: Display pins (fixed strings, formatted wrappers, InvalidMetaMagic field order) and From-routing tests. - crates/metaboard: strengthened wire-shape pins (0x-prefixed hash, where-filters, first/skip argument order and variables, Empty payloads) plus new tests for GraphqlError, Request transport errors, the deserializer boundary on null data, FromHexError and AddressParseError paths. - test/lib/LibMeta.isRainMetaV1_2.t.sol: length-7 boundary probe with a magic byte just past the array end, and a magic-literal pin that cannot co-vary with the META_MAGIC_NUMBER_V1 constant. - Fixed three pre-existing fuzz oracles that asserted raw fuzz data is never rain meta; the fuzzer's counterexample 0xff0a89c674ee7874 (data that itself begins with the magic) falsifies that assumption while the library is correct per spec. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
Warning Review limit reachedNext included review available in 58 minutes. View limit detailsLimit details: You’ve used the included review currently available. You've used all free OSS reviews for now. Wait for the free limit to reset to keep reviewing this public repository. Review configuration: ⚙️ Run configurationConfiguration used: Organization UI Review profile: ASSERTIVE Plan: Pro Plus Run ID: 📒 Files selected for processing (6)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
@coderabbitai review |
|
|
@coderabbitai review |
|
An independently re-derived mutant set (28 Solidity + 42 Rust) probed against the branch found five residual survivors in unit-note targets: - output() with --output-path (file written, stdout silent) - of_chain(1) ethereum set and of_chain(80001) mumbai set - extract_artifact_component_json bytecode arm - schema show op-v1 returning the OpMeta schema Each is now discriminated by strengthening the existing dispatch tests in place (exact URL sets, exact component values, exact file content, schema title). Probe re-run with --only over the five: 5/5 KILLED; full suite green on the unmutated branch. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
main and this branch each fixed the same two fuzz tests: main by assuming/forcing the non-prefix case via LibMeta.isRainMetaV1, this branch by asserting both branches against an independently derived prefix check. Kept this branch's form — the oracle must not be the function under mutation. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
@coderabbitai assess this PR size classification for the totality of the PR with the following criterias and report it in your comment: S/M/L PR Classification Guidelines:This guide helps classify merged pull requests by effort and complexity rather than just line count. The goal is to assess the difficulty and scope of changes after they have been completed. Small (S)Characteristics:
Review Effort: Would have taken 5-10 minutes Examples:
Medium (M)Characteristics:
Review Effort: Would have taken 15-30 minutes Examples:
Large (L)Characteristics:
Review Effort: Would have taken 45+ minutes Examples:
Additional Factors to ConsiderWhen deciding between sizes, also consider:
Notes:
|
Adversarial mutation-test coverage for group g6-cli-plumbing-output-enco (30 behaviours across the CLI plumbing/dispatch, error enum, rain-metaboard-subgraph client, bindings crate, and the LibMeta / LibIMetaBoardV1_2 / LibDescribedByMeta Solidity units), at scanned commit
bba50a7.Probe tool:
nix run github:rainlanguage/adversarial-mutation-test#mutation-probeover exact-string mutants; suites are the CI ground truth (nix develop -c cargo test,nix develop -c forge test). Mutants files were never committed. All kills below are proven by the probe with named killer tests; PREEXISTING kills were attributed in a first pass run before any new test was written.Pre-existing test defect fixed (baseline)
Adding the magic literal
hex"ff0a89c674ee7874"to a test file seeded forge's fuzz dictionary and immediately falsified three pre-existing fuzz oracles on UNMUTATED code (counterexampledata = 0xff0a89c674ee7874):testIsRainMetaV1_2Fuzz,testCheckMetaUnhashedV1_2FuzzandtestCheckMetaHashedV1_2BadMagicGoodHashall asserted that raw fuzz data is never rain meta, which is wrong by spec whenever the data itself begins with the magic. The library is correct; the oracles are fixed in place to branch on the prefix (no assertion was weakened — the magic-prefixed branch now asserts the spec-correct expectation instead of a false one). Filed as #184.Behaviour matrix
Ok(())test_dispatch_buildtest_dispatch_solc_artifacttest_dispatch_subgraphtest_dispatch_magic_lstest_dispatch_schema_ls,test_dispatch_schema_showtest_dispatch_validatetest_dispatch_schema_checktest_dispatch_generate"corrupt meta"mutatedtest_display_fixed_stringstest_display_formatted_wrapperstest_display_invalid_meta_magic_field_ordermeta::types::solidity_abi::v2::tests::test_alltest_from_utf8_error_routes_to_utf8_errortest_get_metabytes_by_hash_graphql_errortest_get_metabytes_by_hash_null_data_is_request_decode_errortest_get_metabytes_by_hash_connection_error_is_requesttest_get_metabytes_by_hash_successtest_get_metabytes_by_hash_emptytest_get_metabytes_by_hash_emptytest_get_metabytes_by_hash_invalid_hex_metatest_get_metabytes_by_subject_successtest_get_metabytes_by_subject_emptytest_get_metabytes_by_subject_invalid_hex_meta(key encoding disputed: #177)test_get_metaboard_addresses_successtest_get_metaboard_addresses_invalid_addresstest_get_metabytes_by_hash_successtest_get_metabytes_by_subject_successtest_get_metaboard_addresses_success< 8guard (8 proceeds)<=8testEmitMetaEmptyBody,testIsRainMetaV1_2Fuzz< 8guard (7 rejected)<7testIsRainMetaV1_2LengthSevenMagicByteBeyondtestIsRainMetaV1_2FuzztestIsRainMetaV1_2FuzztestIsRainMetaV1_2FuzztestIsRainMetaV1_2MagicNumberLiteral(survived the whole pre-existing suite: tests co-varied with the constant)return truetestIsRainMetaV1_2FuzztestCheckMetaUnhashedV1_2FuzztestCheckMetaUnhashedV1_2FuzztestCheckMetaHashedV1_2HappytestCheckMetaHashedV1_2GoodMagicBadHashtestCheckMetaHashedV1_2BadMagicBadHashtestCheckMetaHashedV1_2BadMagicGoodHashtestCheckMetaHashedV1_2HappytestEmitMetaNotRainMetatestEmitMetaHappy(log count)emitsemantics of the inlined call context; asserted bytestEmitMetaHappy(emittercheck) but unfalsifiable by source mutationtestEmitMetaHappytestEmitMetaHappytestEmitMetaHappytestEmitMetaHappy(topic count;testArtifactsCommittedco-fails on the ABI change)testEmitForDescribedAddressMismatch,testEmitForDescribedAddressHappyQA
Discriminating tests:
cli_dispatch.rs(test_dispatch_schema_ls/_schema_show/_validate/_schema_check/_magic_ls/_build/_solc_artifact/_subgraph/_generate),error::tests(test_display_fixed_strings, test_display_formatted_wrappers, test_display_invalid_meta_magic_field_order, test_from_serde_json_routes_to_serde_json_error, test_from_utf8_error_routes_to_utf8_error, test_from_from_utf8_error_routes_to_from_utf8_error),metaboard_client::tests(graphql_error, null_data_is_request_decode_error, connection_error_is_request, invalid_hex_meta x2, invalid_address, plus strengthened success/empty pins),testIsRainMetaV1_2LengthSevenMagicByteBeyond,testIsRainMetaV1_2MagicNumberLiteral— each proven to fail on base by the mutation probe: every one is the named killer of at least one mutant that SURVIVED the pre-change suite in the attribution pass (probe verdict lines below), and all are green on the unmutated branch (cargo 158 passed, forge 18 passed).Oracle: expected values derived independently of the implementation — the metadata-v1 spec magic literal 0xff0a89c674ee7874 (cross-pinned against crates/cli/src/meta/magic.rs), the subgraph GraphQL schema for wire-shape pins (where: {metaHash: …}, first/skip; rendering verified against cynic output, not against the client code), process-level observables of the compiled binary (exit codes, exact stdout lines), and EVM event/ABI semantics for the Solidity units; Display strings are the user-facing contract pinned verbatim.
Category check: AMT run for group g6-cli-plumbing-output-enco — behaviours asked: cli dispatch 8 arms; error Display+From; metaboard CynicClient+client paths+fragments+build.rs; bindings codegen (excluded by design); LibMeta isRainMetaV1/checkMetaUnhashedV1/checkMetaHashedV1; LibIMetaBoardV1_2.emitMeta; LibDescribedByMeta external fetch. All covered in the matrix above; the two UNPROBED rows (compile-time build.rs, codegen-only bindings, emit-context emitter) carry their justification inline.
Mutations applied: full mutant list in the matrix above (file → exact-string mutation → killing test). Attribution pass (no new tests present, commit
bba50a7pristine): 24 Solidity mutants → 22 KILLED by named pre-existing tests, 2 SURVIVED (S02, S07). 29 Rust mutants → 4 KILLED by pre-existing tests (E4, MB01, MB06, MB09), 25 SURVIVED. Probe outputs: batches overmutation-probe <mutants>.toml --only …, JSON reports retained in the run scratchpad.Final pass (this branch, full suites
cargo test= 158 passed /forge test= 18 passed as baseline): all 24 Solidity mutants KILLED; 28/29 Rust mutants KILLED; MB03 SURVIVED and is recorded as an equivalent mutant — the mutated arm is dead code (cynic'sGraphQlResponsedeserializer rejects bodies without data or errors, sodata: Nonewith no errors is unrepresentable). Filed as CynicClientError::Empty is unreachable from CynicClient::query: missing/null data surfaces as a Request decode error #178 with a pinning test for the actual observable.No NO-RUN, no HARNESS-ERROR in the final pass.
Second verification pass (independent mutant derivation)
A fresh session re-derived the mutant set from the behaviour list without reusing the first pass's mutants file (28 Solidity + 42 Rust exact-string mutants) and ran the probe twice: an attribution pass on pristine
bba50a7(Solidity lane: 26/28 killed by named pre-existing tests; the two survivors — length-guard removal and the magic constant literal — are exactly the gaps the first pass'stestIsRainMetaV1_2LengthSevenMagicByteBeyond/testIsRainMetaV1_2MagicNumberLiteralwere written for), then a full pass against this branch.Branch results: Solidity 28/28 KILLED. Rust 36/42 KILLED, 1 survivor is the documented equivalent (
data: Nonedead arm, #178), and 5 survivors were real residual gaps in unit-note targets the first pass had not discriminated:output_path(writes the file, not stdout)test_dispatch_solc_artifact(-o: exact file content + empty stdout)of_chain(1)returns the ethereum set1 => POLYGONtest_dispatch_subgraph(exact 3 ethereum URLs)of_chain(80001)returns the mumbai set80001 => UnsupportedNetworktest_dispatch_subgraph(exact 3 mumbai URLs)bytecodearm is its own componentbytecode => deployedBytecodetest_dispatch_solc_artifact(-c bytecode=="0x60")schema show op-v1returns the OpMeta schemaOpV1 => AuthoringMetaschematest_dispatch_schema_show(title=="OpMeta.")All five were killed by strengthening the existing dispatch tests in place; the second-pass re-probe with
--onlyover these five reports all KILLED, and the fullcli_dispatchsuite is green on the unmutated branch.Issues filed (audit + adversarial)
#177, #178, #179, #180, #181, #182, #184.
🤖 Generated with Claude Code